package com.glsc.ngateway.flowable.controller;


import com.glsc.ngateway.common.api.common.dto.PageDataResult;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.common.api.flowable.dto.demand.FlowableAssigneeDto;
import com.glsc.ngateway.common.api.flowable.dto.param.*;
import com.glsc.ngateway.common.api.flowable.resp.FlowableResponse;
import com.glsc.ngateway.common.api.flowable.resp.ResponseCommentDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.flowable.common.ReBuildMulTaskParam;
import com.glsc.ngateway.flowable.service.FlowableAssigneeService;
import com.glsc.ngateway.flowable.service.process.ProcessService;
import com.glsc.ngateway.flowable.util.GatewayExecutionCompensationUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

@RestController
@RequestMapping(value = "/processNew")
@Api(value = "flowable流程引擎主类processNew", tags = {"flowable流程引擎主类processNew"})
public class ProcessNewController {

    private static Logger logger = LoggerFactory.getLogger(ProcessNewController.class);
    @Resource
    ProcessService processService;
    @Resource
    FlowableAssigneeService flowableAssigneeService;
    @Resource
    GatewayExecutionCompensationUtil util;

    @RequestMapping(method = RequestMethod.POST, value = "/searchDealProcessList")
    @ApiOperation(value = "查询流程实例列表-待办", notes = "查询流程实例列表-待办")
    public FlowableResponse<PageDataResult<ResponseSituationDto>> searchDealProcessList(@RequestParam(value = "pageNum") Integer pageNum, @RequestParam(value = "pageSize") Integer pageSize, @RequestBody ParamSearchDto params) {
        try {
            Pageable pageable = PageRequest.of(PageUtil.initPageNo(pageNum) - 1, PageUtil.initPageSize(pageSize));
            return FlowableResponse.success(processService.searchDealProcessList(pageable, params));
        } catch (Exception e) {
            logger.error("flowable流程查询流程实例列表参数错误！", e);
            return FlowableResponse.error("flowable流程查询流程实例列表参数错误! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "/searchInvolveUserProcessList")
    @ApiOperation(value = "查询流程实例列表-已办", notes = "查询流程实例列表-已办")
    public FlowableResponse<PageDataResult<ResponseSituationDto>> searchInvolveUserProcessList(@RequestParam(value = "pageNum") Integer pageNum, @RequestParam(value = "pageSize") Integer pageSize, @RequestBody ParamSearchDto params) {
        try {
            Pageable pageable = PageRequest.of(PageUtil.initPageNo(pageNum) - 1, PageUtil.initPageSize(pageSize));
            return FlowableResponse.success(processService.searchInvolveUserProcessList(pageable, params));
        } catch (Exception e) {
            logger.error("flowable流程查询流程实例列表参数错误！", e);
            return FlowableResponse.error("flowable流程查询流程实例列表参数错误! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "/searchProcessList")
    @ApiOperation(value = "查询流程实例列表-发起或全部", notes = "查询流程实例列表-发起或全部")
    public FlowableResponse<PageDataResult<ResponseSituationDto>> searchProcessList(@RequestParam(value = "pageNum") Integer pageNum, @RequestParam(value = "pageSize") Integer pageSize, @RequestBody ParamSearchDto params) {
        try {
            Pageable pageable = PageRequest.of(PageUtil.initPageNo(pageNum) - 1, PageUtil.initPageSize(pageSize));
            return FlowableResponse.success(processService.searchProcessList(pageable, params));
        } catch (Exception e) {
            logger.error("flowable流程查询流程实例列表参数错误！", e);
            return FlowableResponse.error("flowable流程查询流程实例列表参数错误! e.getMessage=" + e.getMessage());
        }
    }


    @RequestMapping(method = RequestMethod.POST, value = "/searchUserParticipateProcessList")
    @ApiOperation(value = "查询已办/待办/抄送的流程列表", notes = "查询已办/待办/抄送的流程列表")
    public FlowableResponse searchUserParticipateProcessList(@RequestBody ParticipateParamDto params) {
        try {
            return FlowableResponse.success(processService.searchUserParticipateProcessList(params));
        } catch (Exception e) {
            logger.error("flowable流程查询流程实例列表参数错误！", e);
            return FlowableResponse.error("flowable流程查询流程实例列表参数错误! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.GET, value = "/postCreateCallActivityProcess")
    @ApiOperation(value = "执行发起调用流程的后置任务", notes = "执行发起调用流程的后置任务")
    public FlowableResponse postCreateCallActivityProcess(@RequestParam(value = "processId") String processId, @RequestParam(value = "sysid") String sysid, @RequestParam(value = "userid") String userid) {
        try {
            return FlowableResponse.success(processService.postCreateCallActivityProcess(processId, sysid, userid));
        } catch (Exception e) {
            logger.error("flowable执行发起调用流程的后置任务异常行！", e);
            return FlowableResponse.error("flowable执行发起调用流程的后置任务异常行! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.GET, value = "/resignatedEmpChangeAssignee")
    @ApiOperation(value = "离职人员流程转办", notes = "离职人员流程转办")
    public FlowableResponse resignatedEmpChangeAssignee(@RequestParam(value = "oldAccount") String oldAccount, @RequestParam(value = "newAccount") String newAccount, @RequestParam(value = "sysId") String sysId) {
        try {
            processService.resignatedEmpChangeAssignee(oldAccount, newAccount, sysId);
            return FlowableResponse.success("");
        } catch (Exception e) {
            logger.error("flowable执行离职人员流程转办任务异常行！", e);
            return FlowableResponse.error("flowable执行离职人员流程转办任务异常行! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.GET, value = "/findAssigneeByProcessDefinitionKey")
    @ApiOperation(value = "获取流程会签人", notes = "获取流程会签人")
    public FlowableResponse<List<FlowableAssigneeDto>> findAssigneeByProcessDefinitionKey(@RequestParam(value = "processDefinitionKey") String processDefinitionKey, @RequestParam(value = "sysid") String sysid) {
        try {
            List<FlowableAssigneeDto> assigneeList = flowableAssigneeService.findAssigneeByKey(processDefinitionKey, sysid);
            return FlowableResponse.success(assigneeList);
        } catch (Exception e) {
            logger.error("获取流程会签人异常！", e);
            return FlowableResponse.error("获取流程会签人异常! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.GET, value = "/hasParentProcess")
    @ApiOperation(value = "是否有父流程", notes = "是否有父流程")
    public boolean hasParentProcess(@RequestParam(value = "processDefinitionKey") String processDefinitionKey, @RequestParam(value = "processId") String processId, @RequestParam(value = "sysId") String sysId) {
        return processService.hasParentProcess(processDefinitionKey, processId, sysId);
    }

    /**
     * 获取该task相关信息
     */
    @RequestMapping(method = RequestMethod.GET, value = "getHisTaskInfo")
    @ApiOperation(value = "获取该task相关信息", notes = "获取该task相关信息")
    public FlowableResponse<ResponseSituationDto> getHisTaskInfo(@RequestParam("taskId") String taskId, @RequestParam("sysid") String sysid) {
        try {
            ResponseSituationDto taskInfo = processService.getHisTaskInfo(taskId, sysid);
            return FlowableResponse.success(taskInfo);
        } catch (Exception e) {
            logger.error("获取该task相关信息异常！", e);
            return FlowableResponse.error("获取该task相关信息异常! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "queryFullCommentsByProcessId")
    @ApiOperation(value = "查询该流程的附言列表(包含处理状态)", notes = "查询该流程的附言列表(包含处理状态)")
    public FlowableResponse<PageDataResult<ResponseCommentDto>> queryFullCommentsByProcessId(@RequestParam(value = "pageNum") Integer pageNum, @RequestParam(value = "pageSize") Integer pageSize, @RequestBody ParamCommentDto params) {
        try {
            PageDataResult result = processService.queryFullCommentsByProcessId(pageNum, pageSize, params);
            return FlowableResponse.success(result);
        } catch (Exception e) {
            logger.error("获取该task相关信息异常！", e);
            return FlowableResponse.error("获取该task相关信息异常! e.getMessage=" + e.getMessage());
        }

    }

    /**
     * 创建转发流程
     */
    @RequestMapping(method = RequestMethod.POST, value = "/forward")
    @ApiOperation(value = "创建转发流程", notes = "创建转发流程")
    public FlowableResponse create(@RequestBody ForwardParamDto params) {
        return processService.createForward(params);
    }


    /**
     * 检查异常网关并补偿任务
     */
    @RequestMapping(method = RequestMethod.POST, value = "/checkAndCompensation")
    @ApiOperation(value = "检查异常网关并补偿任务", notes = "检查异常网关并补偿任务")
    public FlowableResponse checkAndCompensation(String processId) {
        try {
            util.checkAndCompensation(processId);
            return FlowableResponse.success("成功");
        } catch (Exception e) {
            logger.error("获取该task相关信息异常！", e);
            return FlowableResponse.error("获取该task相关信息异常! e.getMessage=" + e.getMessage());
        }
    }

    /**
     * 重建节点任务
     */
    @RequestMapping(method = RequestMethod.POST, value = "/reBuildMulTask")
    @ApiOperation(value = "重建节点任务", notes = "重建节点任务")
    public FlowableResponse reBuildMulTask(@RequestBody ReBuildMulTaskParam param) {
        try {
            util.reBuildMulTask(param.getAssigneeList(), param.getTaskKey(), param.getTaskName(), param.getProcessId());
            return FlowableResponse.success("成功");
        } catch (Exception e) {
            logger.error("重建节点任务！", e);
            return FlowableResponse.error("重建节点任务异常! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "queryNotArrivedProcessList")
    @ApiOperation(value = "查询未达某节点的流程列表", notes = "查询未达某节点的流程列表")
    @Deprecated
    public List<String> queryNotArrivedProcessList(@RequestBody ParamSearchArrivedDto paramSearchDto) {
        try {
            return processService.queryNotArrivedProcessList(paramSearchDto);
        } catch (Exception e) {
            logger.error("查询当前未达某节点的流程列表！", e);
            return Collections.emptyList();
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "queryDoingNodeProcessList")
    @ApiOperation(value = "查询处于某节点的流程列表", notes = "查询处于某节点的流程列表")
    public List<String> queryDoingNodeProcessList(@RequestBody ParamSearchArrivedDto paramSearchDto) {
        try {
            return processService.queryDoingNodeProcessList(paramSearchDto);
        } catch (Exception e) {
            logger.error("查询已达某节点的流程列表异常！", e);
            return Collections.emptyList();
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "queryProcessListByStartUser")
    @ApiOperation(value = "查询用户发起流程列表", notes = "查询用户发起流程列表")
    public List<String> queryProcessListByStartUser(@RequestBody ParamStartPorcessDto paramStartPorcessDto) {
        try {
            return processService.queryProcessListByStartUser(paramStartPorcessDto);
        } catch (Exception e) {
            logger.error("查询用户发起流程列表！", e);
            return Collections.emptyList();
        }
    }

    /**
     * 查询当前处理人的流程id
     * @return
     * @throws IOException
     */
    @RequestMapping(method = RequestMethod.GET, value = "/queryProcessListByCurrentAssignee")
    public FlowableResponse<List<String>> queryProcessListByCurrentAssignee(@RequestParam(value = "dealUser" , required = true) String dealUser,
                                                          @RequestParam(value = "processDefineKey" , required = true) String processDefineKey,
                                                          @RequestParam(value = "createProject" , required = true) String createProject) throws IOException {
        try{
            return FlowableResponse.success(processService.queryProcessListByCurrentAssignee(dealUser,processDefineKey,createProject));
        } catch (Exception e){
            logger.error("查询当前处理人的流程id！", e);
            return FlowableResponse.error("查询当前处理人的流程id失败"+e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.POST, value = "/getCopyUserList")
    @ApiOperation(value = "查询抄送用户列表", notes = "查询抄送用户列表")
    public FlowableResponse getCopyUserList(@RequestBody ParticipateParamDto params) {
        try {
            return FlowableResponse.success(processService.getCopyUserList(params));
        } catch (Exception e) {
            logger.error("flowable流程查询流程实例列表参数错误！", e);
            return FlowableResponse.error("flowable流程查询流程实例列表参数错误! e.getMessage=" + e.getMessage());
        }
    }

    @RequestMapping(method = RequestMethod.GET, value = "/clearCache")
    @ApiOperation(value = "清除缓存", notes = "清除缓存")
    public FlowableResponse clearCache(@RequestParam(value = "cacheName", required = true) String cacheName) {
        try {
            processService.clearCache(cacheName);
            return FlowableResponse.success("完成");
        } catch (Exception e) {
            logger.error("清除缓存异常！", e);
            return FlowableResponse.error("清除缓存异常! e.getMessage=" + e.getMessage());
        }
    }

}
